package hu.monitor.server.persistence;

import java.lang.reflect.Constructor;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

public abstract class JpaRepository<T, PK, E extends Exception> {

	@PersistenceContext
	private EntityManager entityManager;

	private final Class<T> entityClass;
	private final Class<E> exceptionClass;

	protected JpaRepository(final Class<T> entityClass, final Class<E> exceptionClass) {
		this.entityClass = entityClass;
		this.exceptionClass = exceptionClass;
	}

	public T findById(final PK primaryKey) throws E{
		if (primaryKey == null) {
			throw new IllegalArgumentException("primaryKey is null");
		}
		final T entity = this.entityManager.find(this.entityClass, primaryKey);
		if (entity == null) {
			final String msg = String.format("Entity [%s] with primary key [%s] not found", this.entityClass.getClass(), primaryKey);
			final E exception = this.createException(msg);
			throw exception;
		}

		return entity;
	}

	protected EntityManager getEntityManager() {
		return this.entityManager;
	}

	private E createException(final String msg) {
		try {
			final Constructor<E> ctor = this.exceptionClass.getConstructor(String.class);
			return ctor.newInstance(msg);
		} catch (final RuntimeException ex) {
			throw ex;
		} catch (final Exception e) {
			throw new ObjectInstantiationException(e);
		}
	}
}
